package com.click.app.webapp.action;

import com.click.app.DateFormatChanger;
import com.click.app.model.BalanceLaundry;
import com.click.app.model.LaundryItem;
import com.click.app.model.LaundryRequest;
import com.click.app.model.LaundryRequestItem;
import com.click.app.model.LaundryType;
import com.click.app.model.ModelSize;
import com.click.app.model.PantDesign;
import com.click.app.model.PeriodPaymentLaundry;
import com.click.app.model.SizeRank;
import com.click.app.model.TradeMark;
import com.click.app.service.BalanceLaundryManager;
import com.click.app.service.GenericManager;
import com.click.app.service.LaundryItemManager;
import com.click.app.service.LaundryRequestItemManager;
import com.click.app.service.LaundryRequestManager;
import com.click.app.service.LaundryStorageManager;
import com.click.app.service.PantDesignManager;
import com.click.app.service.PeriodPaymentLaundryManager;
import com.click.app.service.SeamStorageManager;
import com.click.app.webapp.reportObjects.LaundryFailReceptionTable;
import com.click.app.webapp.reportObjects.LaundryReceptionTable;
import java.util.ArrayList;

import java.util.List;
import java.util.Set;

/**
 * @author Joel Chuca Condo
 */
public class LaundryRequestReceptionAction extends BaseAction {

    private PantDesignManager pantDesignManager;
    private SeamStorageManager seamStorageManager;
    private LaundryRequestItemManager laundryRequestItemManager;
    private LaundryRequestManager laundryRequestManager;
    private GenericManager<TradeMark, Long> tradeMarkManager;
    private GenericManager<LaundryType, Long> laundryTypeManager;
    private GenericManager<SizeRank, Long> sizeRankManager;
    private LaundryItemManager laundryItemManager;
    private LaundryStorageManager laundryStorageManager;
    private LaundryRequest laundryRequest;
    private LaundryRequestItem laundryRequestItem;
    private PantDesign pantDesign;
    private List laundryRequests;
    private List laundryRequestItems;
    private List laundryTypes;
    private List pantDesigns;
    private Set<ModelSize> modelSizes;
    private List<LaundryItem> laundryItems;
    private String[] quantitieIndexs;
    private String[] quantitiesCurrent;
    private String[] quantitiesPriceCurrent;
    private String[] quantitiesFail;
    private String[] quantitiesPriceFail;
    private String[] quantitiesPriceCurrentUser;
    private String[] quantitiesFailUser;
    private String[] quantitiesPriceFailUser;
    private List<Integer> indexsUsers;
    private Long id;
    private Long idLaundryRequest;
    private LaundryReceptionTable laundryReceptionTable;
    private LaundryFailReceptionTable laundryPaysReceptionTable;
    private String receivedDate;
    private BalanceLaundryManager balanceLaundryManager;
    private PeriodPaymentLaundryManager periodPaymentLaundryManager;

    public void setLaundryRequestItemManager(LaundryRequestItemManager laundryRequestItemManager) {
        this.laundryRequestItemManager = laundryRequestItemManager;
    }

    public void setLaundryRequestManager(LaundryRequestManager laundryRequestManager) {
        this.laundryRequestManager = laundryRequestManager;
    }

    public void setLaundryTypeManager(GenericManager<LaundryType, Long> laundryTypeManager) {
        this.laundryTypeManager = laundryTypeManager;
    }

    public void setPantDesignManager(PantDesignManager pantDesignManager) {
        this.pantDesignManager = pantDesignManager;
    }

    public void setSeamStorageManager(SeamStorageManager seamStorageManager) {
        this.seamStorageManager = seamStorageManager;
    }

    public void setTrademarkManager(GenericManager<TradeMark, Long> trademarkManager) {
        this.tradeMarkManager = trademarkManager;
    }

    public void setSizeRankManager(GenericManager<SizeRank, Long> sizeRankManager) {
        this.sizeRankManager = sizeRankManager;
    }

    public void setLaundryItemManager(LaundryItemManager laundryItemManager) {
        this.laundryItemManager = laundryItemManager;
    }

    public void setLaundryStorageManager(LaundryStorageManager laundryStorageManager) {
        this.laundryStorageManager = laundryStorageManager;
    }

    public List getLaundryRequestItems() {
        return laundryRequestItems;
    }

    public List getLaundryRequests() {
        return laundryRequests;
    }

    public List getLaundryTypes() {
        return laundryTypes;
    }

    public List<LaundryItem> getLaundryItems() {
        return laundryItems;
    }

    public List getPantDesigns() {
        return pantDesigns;
    }

    public Set<ModelSize> getModelSizes() {
        return modelSizes;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getIdLaundryRequest() {
        return idLaundryRequest;
    }

    public void setIdLaundryRequest(Long idLaundryRequest) {
        this.idLaundryRequest = idLaundryRequest;
    }

    public LaundryRequest getLaundryRequest() {
        return laundryRequest;
    }

    public void setLaundryRequest(LaundryRequest laundryRequest) {
        this.laundryRequest = laundryRequest;
    }

    public LaundryRequestItem getLaundryRequestItem() {
        return laundryRequestItem;
    }

    public void setLaundryRequestItem(LaundryRequestItem laundryRequestItem) {
        this.laundryRequestItem = laundryRequestItem;
    }

    public LaundryReceptionTable getLaundryReceptionTable() {
        return laundryReceptionTable;
    }

    public PantDesign getPantDesign() {
        return pantDesign;
    }

    public void setPantDesign(PantDesign pantDesign) {
        this.pantDesign = pantDesign;
    }

    public String getReceivedDate() {
        receivedDate = DateFormatChanger.changeDatetoString(laundryRequest.getEndDate());
        return receivedDate;
    }

    public void setReceivedDate(String receivedDate) {
        this.receivedDate = receivedDate;
        laundryRequest.setEndDate(DateFormatChanger.changeStringtoDate(receivedDate));
        ;
    }

    public String laundryUnReceptionList() {
        laundryRequests = laundryRequestManager.getCurrentPeriodUnReception();
        return SUCCESS;
    }

    public String list() {

        if (idLaundryRequest != null) {
            laundryRequest = laundryRequestManager.get(idLaundryRequest);
            getSession().setAttribute("laundryRequest", laundryRequest);
        } else {
            laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
        }

        if (laundryRequest != null) {
            //update
            laundryRequest = laundryRequestManager.get(laundryRequest.getId());
            modelSizes = sizeRankManager.get(new Long(1)).getModelSizes(); // Constant for sizes .... 
            getSession().setAttribute("modelSizes", modelSizes);

            laundryReceptionTable = new LaundryReceptionTable(laundryRequest.getLaundryRequestItems(), laundryItemManager, modelSizes);
            if (!(laundryReceptionTable.isCorrect())) {
                errorMessage(getText("Can't show the table "));
                return ERROR;
            }
            laundryPaysReceptionTable = new LaundryFailReceptionTable(laundryRequest.getLaundryRequestItems(), laundryItemManager, modelSizes);
        } else {
            System.out.println("laundryRequest is null");
            return ERROR;
        }
        return SUCCESS;
    }

    public String edit() {
        System.out.println("LaundryRequestReceptionAction -> edit()");

        laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
        //pantDesigns = seamStorageManager.findByModelAndMaterial(laundryRequest.getTradeMark().getId());
        modelSizes = ((Set<ModelSize>) getSession().getAttribute("modelSizes"));
        laundryTypes = laundryTypeManager.getAll();

        if (id != null) {
            laundryRequestItem = laundryRequestItemManager.get(id);
            pantDesign = laundryRequestItem.getLaundryItems().get(0).getPantDesign();

            laundryItems = laundryItemManager.findByOrderSize(laundryRequestItem.getId());

            quantitiesCurrent = new String[modelSizes.size()];
            quantitiesFail = new String[modelSizes.size()];
            quantitiesPriceCurrent = new String[modelSizes.size()];
            quantitiesPriceFail = new String[modelSizes.size()];
            quantitieIndexs = new String[modelSizes.size()];
            indexsUsers = new ArrayList<Integer>();

            int i = 0;
            for (ModelSize modelSize : modelSizes) {
                int index = 0;
                for (LaundryItem laundryItem : laundryItems) {
                    if (laundryItem.getPantDesign().getModelSize().equals(modelSize)) {
                        break;
                    }
                    index++;
                }
                if (index != laundryItems.size()) {
                    quantitieIndexs[i] = "" + index;
                    quantitiesCurrent[i] = laundryItems.get(index).getQuantity() + "";
                    quantitiesFail[i] = laundryItems.get(index).getFailQuantity() + "";
                    quantitiesPriceCurrent[i] = laundryItems.get(index).getUnitPrice() + "";
                    quantitiesPriceFail[i] = laundryItems.get(index).getFailUnitPrice() + "";
                    indexsUsers.add(i);
                } else {
                    quantitieIndexs[i] = "-1";
                    quantitiesCurrent[i] = 0 + "";
                    quantitiesFail[i] = 0 + "";
                    quantitiesPriceCurrent[i] = 0 + "";
                    quantitiesPriceFail[i] = 0 + "";
                }
                i++;
            }

            quantitiesFailUser = quantitiesFail;
            quantitiesPriceCurrentUser = quantitiesPriceCurrent;
            quantitiesPriceFailUser = quantitiesPriceFail;

            getSession().setAttribute("quantitiesCurrent", quantitiesCurrent);
            getSession().setAttribute("quantitieIndexs", quantitieIndexs);
            getSession().setAttribute("quantitiesFail", quantitiesFail);
            getSession().setAttribute("quantitiesPriceCurrent", quantitiesPriceCurrent);
            getSession().setAttribute("quantitiesPriceFail", quantitiesPriceFail);
            getSession().setAttribute("indexsUsers", indexsUsers);

        }


        System.out.println("LaundryRequestReceptionAction -> end edit()");

        return SUCCESS;
    }

    public String save() throws Exception {
        System.out.println("LaundryRequestReceptionAction -> save()");
        if (cancel != null) {
            return CANCEL;
        }

        boolean isNew = false;
        isNew = (laundryRequestItem.getId() == null);

        laundryRequest = (LaundryRequest) getSession().getAttribute("laundryRequest");
        laundryRequest = laundryRequestManager.get(laundryRequest.getId());

        if (!isNew) {
            // -------------  update old datas ------------
            LaundryRequestItem laundryRequestItemOld = laundryRequestItemManager.get(laundryRequestItem.getId());
            laundryItems = new ArrayList<LaundryItem>();
            //List<LaundryItem> laundryItemsOld = laundryRequestItemOld.getLaundryItems();
            for (LaundryItem laundryItem : laundryRequestItemOld.getLaundryItems()) {
                laundryItems.add(laundryItem);
            }

            PantDesign pantDesignOld = laundryRequestItemOld.getLaundryItems().get(0).getPantDesign();

            modelSizes = ((Set<ModelSize>) getSession().getAttribute("modelSizes"));
            quantitieIndexs = ((String[]) getSession().getAttribute("quantitieIndexs"));
            quantitiesCurrent = ((String[]) getSession().getAttribute("quantitiesCurrent"));

            quantitiesFail = ((String[]) getSession().getAttribute("quantitiesFail"));
            quantitiesPriceCurrent = ((String[]) getSession().getAttribute("quantitiesPriceCurrent"));
            quantitiesPriceFail = ((String[]) getSession().getAttribute("quantitiesPriceFail"));
            indexsUsers = ((List<Integer>) getSession().getAttribute("indexsUsers"));

            for (int i = 0; i < quantitiesFailUser.length; i++) {
                Integer index = indexsUsers.get(i);
                quantitiesFail[index] = quantitiesFailUser[i];
                quantitiesPriceCurrent[index] = quantitiesPriceCurrentUser[i];
                quantitiesPriceFail[index] = quantitiesPriceFailUser[i];
            }

            laundryItems = laundryItemManager.findByOrderSize(laundryRequestItemOld.getId());
            Integer failTotalQuantity = 0;
            Integer clothesTotalQuantity = 0;
            Double priceXclothesTotal = 0.0D;
            Double priceFailTotal = 0.0D;

            for (int i = 0; i < quantitiesCurrent.length; i++) {
                if (!quantitieIndexs[i].equals("-1")) {
                    Integer failQuantity = Integer.parseInt(quantitiesFail[i]);
                    LaundryItem lItem = laundryItems.get(Integer.parseInt(quantitieIndexs[i]));
                    if (failQuantity <= Integer.parseInt(quantitiesCurrent[i])) {
                        lItem.setFailQuantity(failQuantity);
                    } else {
                        errorMessage("Error: Fail quantity exceeded the good quantity");
                        return "reload";
                    }
                    failTotalQuantity += failQuantity;
                    // ------------------------------------------------------
                    Double priceXclothes = Double.parseDouble(quantitiesPriceCurrent[i]);
                    if (priceXclothes >= 0) {
                        lItem.setUnitPrice(priceXclothes);
                    } else {
                        errorMessage("Error: Fail price");
                        return "reload";
                    }
                    priceXclothesTotal += priceXclothes * Integer.parseInt(quantitiesCurrent[i]);
                    lItem.setUnitTotalPrice(priceXclothes * Integer.parseInt(quantitiesCurrent[i]));
                    // ------------------------------------------------------

                    Double priceXFail = Double.parseDouble(quantitiesPriceFail[i]);
                    if (priceXFail >= 0) {
                        lItem.setFailUnitPrice(priceXFail);
                    } else {
                        errorMessage("Error: Fail price fail");
                        return "reload";
                    }
                    lItem.setTotalPrice((lItem.getQuantity() * lItem.getUnitPrice()) - (lItem.getFailQuantity() * lItem.getFailUnitPrice()));
                    lItem.setFailTotalPrice(lItem.getFailQuantity() * lItem.getFailUnitPrice());

                    priceFailTotal += priceXFail * Integer.parseInt(quantitiesFail[i]);
                }
            }

            laundryRequestItemOld.setLaundryItems(laundryItems);
            laundryRequestItemOld.setFailUnitPrice(0.0D);
            laundryRequestItemOld.setFailQuantity(failTotalQuantity);
            laundryRequestItemOld.setFailTotalPrice(priceFailTotal);
            laundryRequestItemOld.setUnitTotalPrice(priceXclothesTotal);
            laundryRequestItemOld.setTotalPrice(priceXclothesTotal - priceFailTotal);

            laundryRequestItemOld = laundryRequestItemManager.save(laundryRequestItemOld);

            laundryRequest = laundryRequestItemOld.getLaundryRequest();
            laundryRequest.setCurrentTotalPrice(laundryRequest.getCurrentTotalPrice() + laundryRequestItemOld.getTotalPrice());
            laundryRequest.setTotalPrice(laundryRequest.getCurrentTotalPrice() + laundryRequestItemOld.getTotalPrice());
            laundryRequest.setFailTotalPrice(laundryRequest.getFailTotalPrice() + priceFailTotal);
            laundryRequest.setClothesTotalPrice(laundryRequest.getClothesTotalPrice() + priceXclothesTotal);

            PeriodPaymentLaundry periodPaymentLaundry = laundryRequest.getPeriodPaymentLaundry();
            LaundryRequest laundryRequest = laundryRequestItemOld.getLaundryRequest();
            BalanceLaundry balanceLaundry = laundryRequest.getBalanceLaundry();
            balanceLaundry.setAmountWon(balanceLaundry.getAmountPaid() + priceXclothesTotal);
            balanceLaundry.setAmountPaid(balanceLaundry.getAmountPaid() + failTotalQuantity);
            balanceLaundry.setBalance(periodPaymentLaundry.getCurrentAmount() + laundryRequestItemOld.getTotalPrice());
            balanceLaundry = balanceLaundryManager.save(balanceLaundry);

            periodPaymentLaundry.setAmountWon(periodPaymentLaundry.getAmountWon() + laundryRequestItemOld.getTotalPrice());
            periodPaymentLaundry.setCurrentAmount(periodPaymentLaundry.getCurrentAmount() + laundryRequestItemOld.getTotalPrice());
            periodPaymentLaundry.setAmountPayment(periodPaymentLaundry.getAmountPayment() + laundryRequestItemOld.getFailTotalPrice());
            periodPaymentLaundryManager.save(periodPaymentLaundry);

        }

        getSession().setAttribute("laundryRequestItem", null);

        saveMessage(getText("laundryRequestItem.updated"));
        System.out.println("LaundryRequestReceptionAction -> end save()");
        return INPUT;
    }

    public String delete() {
        return "delete";
    }

    public String help() {
        return SUCCESS;
    }

    public String send() {
        if (cancel != null) {
            return CANCEL;
        }

        laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
        laundryRequest = laundryRequestManager.get(laundryRequest.getId());
        laundryRequest.setEndDate(DateFormatChanger.changeStringtoDate(receivedDate));

//        if (laundryRequest.getEndDate() != null) {
//            laundryRequest = laundryRequestManager.get(laundryRequest.getId());
//            List<LaundryRequestItem> laundryRequestItems = laundryRequest.getLaundryRequestItems();
//
//            // update laundry storage
//            for (LaundryRequestItem laundryRequestItem : laundryRequestItems) {
//                for (LaundryItem laundryItem : laundryRequestItem.getLaundryItems()) {
//                    LaundryStorage laundryStorage = laundryStorageManager.findByPantDesignAndTradeMark(laundryItem.getPantDesign().getId(), laundryRequest.getTradeMark().getId());
//                    //LaundryStorage laundryStorage= null;
//                    if (laundryStorage != null) {
//                        laundryStorage.setStock(laundryStorage.getStock() + laundryItem.getQuantity());
//                    } else {
//                        laundryStorage = new LaundryStorage();
//                        laundryStorage.setPantDesign(laundryItem.getPantDesign());
//                        laundryStorage.setTradeMark(laundryRequest.getTradeMark());
//                        laundryStorage.setStock(laundryItem.getQuantity());
//                        laundryStorage.setStockLimit(0);
//                    }
//
//                    laundryStorage = laundryStorageManager.save(laundryStorage);
//                }
//            }
//        } else {
//            errorMessage("There is not Date");
//            return "error";
//        }

        laundryRequest = laundryRequestManager.save(laundryRequest);

        getSession().setAttribute("laundryRequest", null);
        getSession().setAttribute("laundryRequestItem", null);
        getSession().setAttribute("pantDesign", null);

        saveMessage("clothes were sended to storage");
        return SUCCESS;
    }

    public String[] getQuantitiesCurrent() {
        return quantitiesCurrent;
    }

    public void setQuantitiesCurrent(String[] quantitiesCurrent) {
        this.quantitiesCurrent = quantitiesCurrent;
    }

    public String[] getQuantitiesFail() {
        return quantitiesFail;
    }

    public void setQuantitiesFail(String[] quantitiesFail) {
        this.quantitiesFail = quantitiesFail;
    }

    public String[] getQuantitiesPriceCurrent() {
        return quantitiesPriceCurrent;
    }

    public void setQuantitiesPriceCurrent(String[] quantitiesPriceCurrent) {
        this.quantitiesPriceCurrent = quantitiesPriceCurrent;
    }

    public String[] getQuantitiesPriceFail() {
        return quantitiesPriceFail;
    }

    public void setQuantitiesPriceFail(String[] quantitiesPriceFail) {
        this.quantitiesPriceFail = quantitiesPriceFail;
    }

    public GenericManager<TradeMark, Long> getTradeMarkManager() {
        return tradeMarkManager;
    }

    public void setTradeMarkManager(GenericManager<TradeMark, Long> tradeMarkManager) {
        this.tradeMarkManager = tradeMarkManager;
    }

    public String[] getQuantitieIndexs() {
        return quantitieIndexs;
    }

    public void setQuantitieIndexs(String[] quantitieIndexs) {
        this.quantitieIndexs = quantitieIndexs;
    }

    public String[] getQuantitiesFailUser() {
        return quantitiesFailUser;
    }

    public void setQuantitiesFailUser(String[] quantitiesFailUser) {
        this.quantitiesFailUser = quantitiesFailUser;
    }

    public String[] getQuantitiesPriceCurrentUser() {
        return quantitiesPriceCurrentUser;
    }

    public void setQuantitiesPriceCurrentUser(String[] quantitiesPriceCurrentUser) {
        this.quantitiesPriceCurrentUser = quantitiesPriceCurrentUser;
    }

    public String[] getQuantitiesPriceFailUser() {
        return quantitiesPriceFailUser;
    }

    public void setQuantitiesPriceFailUser(String[] quantitiesPriceFailUser) {
        this.quantitiesPriceFailUser = quantitiesPriceFailUser;
    }

    public BalanceLaundryManager getBalanceLaundryManager() {
        return balanceLaundryManager;
    }

    public void setBalanceLaundryManager(BalanceLaundryManager balanceLaundryManager) {
        this.balanceLaundryManager = balanceLaundryManager;
    }

    public PeriodPaymentLaundryManager getPeriodPaymentLaundryManager() {
        return periodPaymentLaundryManager;
    }

    public void setPeriodPaymentLaundryManager(PeriodPaymentLaundryManager periodPaymentLaundryManager) {
        this.periodPaymentLaundryManager = periodPaymentLaundryManager;
    }

    public LaundryFailReceptionTable getLaundryPaysReceptionTable() {
        return laundryPaysReceptionTable;
    }

    public void setLaundryPaysReceptionTable(LaundryFailReceptionTable laundryPaysReceptionTable) {
        this.laundryPaysReceptionTable = laundryPaysReceptionTable;
    }
}
